package com.example.demo.utils;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.demo.mapper.FundAccountMapper;
import com.example.demo.pojo.Accounts.FundAccounts;
import com.example.demo.pojo.Order.CreatOrderPojo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;

@Service
public class FundAccountUtils {
    @Resource
    private FundAccountMapper fundAccountMapper;

    private StockPositionsUtils stockPositionsUtils;

    private static Logger logger = LogManager.getLogger();

    //当凌晨的时候自动刷新冻结资金(清零)
    @Scheduled(cron = "0 0 0 * * ?")
    @Transactional
    public void resetFrozenFund() {
        fundAccountMapper.resetFrozenFund();
    }

    public boolean updateFundAccountsAfterTransaction(
            Integer id,
            Integer userId,
            BigDecimal price,
            int quantity,
            int multiply,
            BigDecimal costPrice) {

        // 计算交易金额大小(取小数点后两位)
        BigDecimal divide = BigDecimal.valueOf(quantity).divide(BigDecimal.valueOf(multiply), 0, RoundingMode.HALF_UP);
        BigDecimal priceTransaction = price
                .multiply(divide)
                .setScale(2, RoundingMode.HALF_UP);

        // 查询平台账户信息
        UpdateWrapper<FundAccounts> fundAccountsQueryWrapper = new UpdateWrapper<>();
        fundAccountsQueryWrapper.eq("account_id", id)
                .eq("user_id", userId);
        FundAccounts fundAccounts = fundAccountMapper.selectOne(fundAccountsQueryWrapper);

        // 修改平台比赛账户信息
        fundAccounts.setTotalAsset(fundAccounts.getTotalAsset().add(priceTransaction));
        fundAccounts.setAvailableFund(fundAccounts.getAvailableFund().add(priceTransaction));
        fundAccounts.setAccountId(fundAccounts.getAccountId());
        fundAccounts.setBankAccount(fundAccounts.getBankAccount());
        fundAccounts.setUserId(fundAccounts.getUserId());

        // 计算持仓盈亏(平均价格减去现价*卖出股数)
        BigDecimal positionProfitLoss = (costPrice.subtract(price))
                .multiply(divide)
                .setScale(2, RoundingMode.HALF_UP);
        fundAccounts.setPositionProfitLoss(fundAccounts.getPositionProfitLoss()
                .subtract(positionProfitLoss)
                .setScale(2, RoundingMode.HALF_UP));

        // 计算当前手头股票市值（先设为零）
        fundAccounts.setPositionValue(BigDecimal.ZERO);

        return fundAccountMapper.update(fundAccounts, fundAccountsQueryWrapper) > 0;
    }

    // 新，卖出持仓股票并对FundAccounts表进行更新
    public boolean updateFundAccountsAfterTransactionNew(
            CreatOrderPojo creatOrderPojo,
            Integer userId,
            BigDecimal costPrice,
            BigDecimal profitLoss,
            Integer orderType) {

        // 如果为限价卖出，则返回
        if(orderType.equals(4)){
            logger.info("本次挂单为限价卖出，在flink模块进行处理!");
            return true;
        }

        // 更新FundAccounts表所需的基本信息
        Integer id = creatOrderPojo.getCompetitionid();
        BigDecimal price = creatOrderPojo.getPrice();
        int quantity = creatOrderPojo.getQuantity();
        int multiply = creatOrderPojo.getMultiply();

        // 查询平台账户信息,使用大赛id和用户id可唯一确定一张表
        UpdateWrapper<FundAccounts> fundAccountsQueryWrapper = new UpdateWrapper<>();
        fundAccountsQueryWrapper.eq("competition_id", creatOrderPojo.getCompetitionid())
                .eq("user_id", userId);
        FundAccounts fundAccounts = fundAccountMapper.selectOne(fundAccountsQueryWrapper);

        // 计算卖出金额大小 挂单价格乘以卖出数量
        BigDecimal priceTransaction = price.multiply(BigDecimal.valueOf(quantity))
                .setScale(2, RoundingMode.HALF_UP);


        // 修改平台比赛账户信息
        // 总可用资金 不变
        // 总冻结资金 加上这部分卖出的资金
        fundAccounts.setFrozenFund(fundAccounts.getFrozenFund().add(priceTransaction));
        // 总成本价 原总成本价-(卖出股票的原持仓成本*卖出数量）
        fundAccounts.setAmount(fundAccounts.getAmount()
                .subtract(costPrice.multiply(BigDecimal.valueOf(quantity)))
                .setScale(2, RoundingMode.HALF_UP));
        // 总持仓盈亏 原总持仓盈亏- 原这部分股票的盈亏 + 卖出的这部分股票的盈亏(卖出金额-成本价*卖出数量)
        fundAccounts.setPositionProfitLoss(fundAccounts.getPositionProfitLoss()
                .subtract(profitLoss)
                .add(priceTransaction.subtract(costPrice.multiply(BigDecimal.valueOf(quantity))))
                .setScale(2, RoundingMode.HALF_UP));
        // 总持仓市值 原总持仓市值-卖出股票市值
        fundAccounts.setPositionValue(fundAccounts.getPositionValue()
                .subtract(priceTransaction)
                .setScale(2, RoundingMode.HALF_UP));
        // 更新总资产
        fundAccounts.setTotalAsset(fundAccounts.getAvailableFund() // 总可用资金
                .add(fundAccounts.getFrozenFund()) // 总冻结资金
                .add(fundAccounts.getPositionValue()) // 总持仓市值
                .setScale(2, RoundingMode.HALF_UP));

        return fundAccountMapper.update(fundAccounts, fundAccountsQueryWrapper) > 0;
    }

    //第二次以上购买
    public boolean updateFundAccountsForBuyTransaction(
            Integer id,
            Integer userId,
            BigDecimal price,
            int quantity,
            int multiply) {

        // 查询平台账户信息
        UpdateWrapper<FundAccounts> fundAccountsQueryWrapper = new UpdateWrapper<>();
        fundAccountsQueryWrapper.eq("account_id", id)
                .eq("user_id", userId);
        FundAccounts fundAccounts = fundAccountMapper.selectOne(fundAccountsQueryWrapper);


        // 计算购买所需金额
        BigDecimal requiredAmount = price.multiply(BigDecimal.valueOf(quantity).divide(BigDecimal.valueOf(multiply), 0, RoundingMode.HALF_UP));

        // 检查可用余额是否足够
        if (fundAccounts.getAvailableFund().compareTo(requiredAmount) < 0) {
            return false; // 可用余额不足，操作失败
        }

        // 计算账户可用资金(可用资产-成交价格*购入股票数量)
        fundAccounts.setAvailableFund(fundAccounts.getAvailableFund()
                .subtract(requiredAmount)
                .setScale(2, RoundingMode.HALF_UP));

        // 计算冻结资产(成交价格*购入股票数量)
        fundAccounts.setFrozenFund(fundAccounts.getFrozenFund()
                .add(requiredAmount)
                .setScale(2, RoundingMode.HALF_UP));

        // 计算持仓市值(现在手头的股票市值)
        fundAccounts.setPositionValue(fundAccounts.getPositionValue());

        // 计算市值盈亏
        fundAccounts.setPositionProfitLoss(BigDecimal.ZERO);

        // 更新平台账户信息
        int update = fundAccountMapper.update(fundAccounts, fundAccountsQueryWrapper);

        return update > 0; // 如果更新成功返回true，否则返回false
    }


    //新，买入某支股票后对FundAccounts表进行更新，无论其是否为第一次买入
    public boolean updateFundAccountsForBuyTransactionNew(
            CreatOrderPojo creatOrderPojo,
            Integer userId,
            Integer orderType
        ) {

        // 更新FundAccounts表所需的基本信息
        Integer id = creatOrderPojo.getCompetitionid();
        BigDecimal price = creatOrderPojo.getPrice();
        int quantity = creatOrderPojo.getQuantity();
        int multiply = creatOrderPojo.getMultiply();

        // 获得交易类型
//        Integer orderType = stockPositionsUtils.getOrderType(creatOrderPojo);
        // 上面获得交易类型的代码会抛空指针异常，原因不详，所以我直接传值进来

        // 查询平台账户信息,使用大赛id和用户id可唯一确定一张表
        UpdateWrapper<FundAccounts> fundAccountsQueryWrapper = new UpdateWrapper<>();
        fundAccountsQueryWrapper.eq("competition_id", creatOrderPojo.getCompetitionid())
                .eq("user_id", userId);
        FundAccounts fundAccounts = fundAccountMapper.selectOne(fundAccountsQueryWrapper);

        // 计算需要的资金(成本价)
        BigDecimal requiredAmount = price.multiply(BigDecimal.valueOf(quantity)).setScale(2, RoundingMode.HALF_UP);
        // 检查可用余额是否足够
        if (fundAccounts.getAvailableFund().compareTo(requiredAmount) < 0) {
            logger.info("FundAccounts表中的可用余额不足，操作失败！");
            return false; // 可用余额不足，操作失败
        }

        // 计算可用资金：原有可用资金-成交价格*购入股票数量
        fundAccounts.setAvailableFund(fundAccounts.getAvailableFund()
                .subtract(requiredAmount)
                .setScale(2, RoundingMode.HALF_UP));

        // 即时买入时更新以下字段
        if(orderType.equals(1)){
            // 计算持仓市值(现在手头的股票市值)
            fundAccounts.setPositionValue(fundAccounts.getPositionValue()
                    .add(creatOrderPojo.getLast().multiply(BigDecimal.valueOf(quantity)))
                    .setScale(2, RoundingMode.HALF_UP));
            // 计算成本价总金额
            fundAccounts.setAmount(fundAccounts.getAmount()
                    .add(requiredAmount)
                    .setScale(2, RoundingMode.HALF_UP));
            // 计算总持仓盈亏
            // 最新价减去挂单价格再乘以数量即得盈亏
            BigDecimal PositionProfitLoss = (creatOrderPojo.getLast()
                    .multiply(BigDecimal.valueOf(quantity))) // 最新价总价
                    .subtract(requiredAmount) // 减去挂单总价即此次挂单产生的盈亏
                    .setScale(2, RoundingMode.HALF_UP);
            fundAccounts.setPositionProfitLoss(fundAccounts.getPositionProfitLoss()
                    .add(PositionProfitLoss));
            // 更新总资产
            fundAccounts.setTotalAsset(fundAccounts.getAvailableFund() // 总可用资金
                    .add(fundAccounts.getFrozenFund()) // 总冻结资金
                    .add(fundAccounts.getPositionValue()) // 总持仓市值
                    .setScale(2, RoundingMode.HALF_UP));

        }

        // 如果为限价买入，则更新冻结资金
        if(orderType.equals(2)) {
            fundAccounts.setFrozenFund(fundAccounts.getFrozenFund()
                    .add(requiredAmount)
                    .setScale(2, RoundingMode.HALF_UP));
        }

        // 更新平台账户信息
        int update = fundAccountMapper.update(fundAccounts, fundAccountsQueryWrapper);

        return update > 0; // 如果更新成功返回true，否则返回false
    }

    //第一次购买市价股票
    public boolean updateFundAccountsFirstBuyTransaction(
            Integer id,
            Integer userId,
            BigDecimal price,
            int quantity,
            int multiply) {

        // 查询平台账户信息
        UpdateWrapper<FundAccounts> fundAccountsQueryWrapper = new UpdateWrapper<>();
        fundAccountsQueryWrapper.eq("account_id", id)
                .eq("user_id", userId);
        FundAccounts fundAccounts = fundAccountMapper.selectOne(fundAccountsQueryWrapper);

        // 计算成交总金额
        BigDecimal totalPrice = price.multiply(BigDecimal.valueOf(quantity).divide(BigDecimal.valueOf(multiply), 0, RoundingMode.HALF_UP));

        // 检查可用余额是否足够
        if (fundAccounts.getAvailableFund().compareTo(totalPrice) < 0) {
            return false; // 可用余额不足，操作失败
        }
        // 计算账户可用资金(可用资产-成交价格*购入股票数量)
        fundAccounts.setAvailableFund(fundAccounts.getAvailableFund()
                .subtract(totalPrice)
                .setScale(2, RoundingMode.HALF_UP));

        // 计算冻结资产(成交价格*购入股票数量)
        fundAccounts.setFrozenFund(fundAccounts.getFrozenFund()
                .add(totalPrice)
                .setScale(2, RoundingMode.HALF_UP));

        // 计算持仓市值(现在手头的股票市值)
        fundAccounts.setPositionValue(BigDecimal.ZERO);

        // 计算总资产减去成交总金额
        fundAccounts.setTotalAsset(fundAccounts.getTotalAsset());

        // 计算市值盈亏
        fundAccounts.setPositionProfitLoss(BigDecimal.ZERO);

        // 更新平台账户信息
        int update = fundAccountMapper.update(fundAccounts, fundAccountsQueryWrapper);

        return update > 0; // 如果更新成功返回true，否则返回false
    }


}
